<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>使用XHR封装ajax请求参数</title>
</head>

<body>
    <button onclick="btnGet()">get请求</button>
    <button onclick="btnPost()">post请求</button>
    <button onclick="btnPut()">put请求</button>
    <button onclick="btnDelete()">delete请求</button>
    <script>
        function axios({
            url,
            method = "GET",
            params = {},
            data = {}
        }) {
            // 返回一个 promise 对象
            return new Promise((resolve, reject) => {
                // 处理 method（转成大写）
                method = method.toUpperCase();

                // 处理query参数(拼接 到url上) id=1&xx=abc
                /* {
                    id: 1,
                    xxx: 'abc'
                } */
                let queryString = '';
                Object.keys(params).forEach(key => {
                    queryString += `${key}=${params[key]}&`
                }) // 以 对象的属性 为元素的数组
                if (queryString) {
                    // 去除最后的&
                    queryString = queryString.substring(0, queryString.length - 1);
                    url += '?' + queryString
                }

                // 1. 执行异步ajax请求
                // 创建 xhr对象
                const request = new XMLHttpRequest();

                // 打开连接(初始化请求，没有请求)
                request.open(method, url, true)

                // 发送请求
                if (method === 'GET' || method === 'DELETE') {
                    request.send()
                } else if (method === 'POST' || method === 'PUT') {
                    request.setRequestHeader('Content-Type',
                        'application/json;charset=utf-8'); // 告诉服务器请求体的格式是json
                    request.send(JSON.stringify(data)); // 发送json格式请求体参数
                }

                // 绑定状态改变的监听
                request.onreadystatechange = function () {
                    // 如果请求没有完成，直接结束
                    if (request.readyState !== 4) {
                        return
                    }
                    // 如果响应状态码在[200,300)之间代表成功，否则失败（ axios 源码里就是这么写的）
                    // 用解构的状态取值
                    const {
                        status,
                        statusText
                    } = request

                    // 2.1 如果请求成功了，调用resolve()
                    if (status >= 200 & status <= 299) {
                        const response = {
                            data: JSON.parse(request.response),
                            status,
                            statusText
                        }
                        resolve(response)
                    } else {
                        // 2.2 如果请求失败了，调用reject()
                        reject(new Error('request error status is' + status))
                    }
                }
            })
        }

        function btnGet() {
            axios({
                url: 'http://localhost:3000/posts',
                // method: "GET",
                params: {
                    id: 1,
                    xxx: 'abc'
                }
            }).then(
                response => {
                    console.log(response);
                },
                error => {
                    alert(error.message)
                })
        }

        function btnPost() {
            axios({
                url: 'http://localhost:3000/posts',
                method: "POST",
                data: {
                    "title": "json-server---",
                    "author": "typicode---"
                }
            }).then(
                response => {
                    console.log(response);
                },
                error => {
                    alert(error.message)
                })
        }

        function btnPut() {
            axios({
                url: 'http://localhost:3000/posts/2',
                method: "put",
                data: {
                    "title": "json-server+++",
                    "author": "typicode+++"
                }
            }).then(
                response => {
                    console.log(response);
                },
                error => {
                    alert(error.message)
                })
        }

        function btnDelete() {
            axios({
                url: 'http://localhost:3000/posts/2',
                method: "delete"
            }).then(
                response => {
                    console.log(response);
                },
                error => {
                    alert(error.message)
                })
        }
    </script>
</body>

</html>